
package cfar.actors.distributed;

import cfar.actors.Location;
import cfar.actors.Message;
import cfar.actors.RemoteActor;
import cfar.ff.data.Maybe;
import cfar.utils.IO;
import java.io.IOException;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Spawns other actors in local thread, then communicates the location info to the caller
 * @author badi
 */
public class ActorServer extends CRCActor {

    public ActorServer(final String sync_dir, final String suffix) throws IOException {
        super(sync_dir, suffix);
    }

    @Override
    protected void act(Message msg, Socket client){
        if(msg.signal instanceof Signal.Spawn){
            try {
                Location loc = spawn_worker();
                Message m = new Message(Signal.WorkerLocation, loc);
                IO.write_object(m, client.getOutputStream());
            } catch (IOException ex) {
                Logger.getLogger(ActorServer.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else { unknown_signal(msg); }
    }

    private Location spawn_worker(){
        Maybe<Location> loc = Maybe.<Location>nothing();
        int max_tries = 9;
        for(int i = 0; i < max_tries; i++){
            RemoteActor actor = new ActorF0();
            if(actor.my_address.isJust && actor.my_port.isJust){
                loc = Maybe.just(new Location(actor.my_address.fromJust(), actor.my_port.fromJust()));
                new Thread(actor).start();
                break;
            }
            else continue;
        }
        if(loc.isJust)
            return loc.fromJust();
        else
            throw new RuntimeException("Cannot create ActorF0");
    }
}
